package org.ewicom.ppsaddressbook;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.sqlite.SQLiteDatabase;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;

//TODO ZMIANY: zapis pliku w cash, trzymanie tylko url, czyszczenie cash
//TODO: jak zablokowac przed wygasnieciem ekran?
// TODO Uzycie androidowego httpUrlConection
// TODO Tekt dla progres i tost parsowany ze string.xml
public class SplashActivity extends Activity {

	private static final String TAG = "SplashActivity";
	private static final int SPLASH_SCREEN_DURATION = 1000; // 5 sek.

	private static final String PREFERENCES_FILE = "pps_settings_file";
	private static final String DATABASE_PATH = "/data/data/org.ewicom.ppsaddressbook/databases/";
	private static final String DATABASE_NAME = "pps_addressbook.db";
	private static final String DATABASE_UPDATE_FILE_URL = "http://pps-addressbook.googlecode.com/files/pps_addressbook_update.txt";

	private static final String PREFERENCE_KEY_DATABASE_FILE_URL = "databaseFileUrl";

	private static String sDatabaseFileUrl;
	private static File sCasheFile;

	private SharedPreferences settings;
	private Editor editor;
	private TimerTask timerTask;
	private Timer timer;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_splash);

		settings = getSharedPreferences(PREFERENCES_FILE, MODE_PRIVATE);
		sDatabaseFileUrl = settings.getString(PREFERENCE_KEY_DATABASE_FILE_URL,
				"NO_URL");
		editor = settings.edit();

		timerTask = new TimerTask() {

			@Override
			public void run() {
				finish();
				Intent intent = new Intent(SplashActivity.this, UnitsList.class);
				startActivity(intent);
			}
		};

		timer = new Timer();

		if (isOnline()) {
			new CheckUpdateTask(this).execute();
		} else {
			if (sDatabaseFileUrl.equals("NO_URL")) {
				AlertDialog.Builder builder = new AlertDialog.Builder(this);
				builder.setMessage(
						"Aplikacja wymaga polaczenia internetowego do inicjalizacji")
						.setCancelable(false)
						.setNeutralButton("OK",
								new DialogInterface.OnClickListener() {

									@Override
									public void onClick(DialogInterface dialog,
											int which) {
										SplashActivity.this.finish();
									}
								});

				AlertDialog noNetworkAlertDialog = builder.create();
				noNetworkAlertDialog.show();
			}else{
				timer.schedule(timerTask, SPLASH_SCREEN_DURATION);
			}	
		}

	}
	
	@Override
	protected void onPause() {
		editor.putString(PREFERENCE_KEY_DATABASE_FILE_URL, sDatabaseFileUrl);
		editor.commit();
		super.onPause();
	}

	private void updateDatabase() {
		new CopyDatabaseFile(this).execute();
	}

	private void downloadDatabaseFile() {
		new DownloadDatabaseFileTask(this).execute();
	}

	private boolean isOnline() {
		ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo netInfo = connManager.getActiveNetworkInfo();
		return (netInfo != null && netInfo.isConnected());
	}

	private class CheckUpdateTask extends AsyncTask<Void, Void, Boolean> {

		private Activity activity;

		private ProgressDialog progressDialog;

		private URLConnection urlConnection;
		private URL url;

		private String databaseFileUrl;

		public CheckUpdateTask(Activity activity) {
			this.activity = activity;

			progressDialog = new ProgressDialog(activity);
			progressDialog.setMessage("Sprawdzam aktualizacje");
			progressDialog.setIndeterminate(true);
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			progressDialog.show();
		}

		@Override
		protected Boolean doInBackground(Void... params) {
			try {
				url = new URL(DATABASE_UPDATE_FILE_URL);

				urlConnection = url.openConnection();
				urlConnection.connect();

				BufferedReader in = new BufferedReader(new InputStreamReader(
						url.openStream()));

				String str;
				while ((str = in.readLine()) != null) {
					Log.v(TAG, str);
					databaseFileUrl = str;
				}

				in.close();

				if (databaseFileUrl.equals(sDatabaseFileUrl)) {
					return false;
				}

			} catch (MalformedURLException e) {
				Log.e(TAG, "Bledny adres pliku aktualizacji");
			} catch (IOException e) {
				e.printStackTrace();
			}

			sDatabaseFileUrl = databaseFileUrl;
			return true;
		}

		@Override
		protected void onPostExecute(Boolean updateNesesery) {
			super.onPostExecute(updateNesesery);
			progressDialog.dismiss();
			if (updateNesesery) {
				downloadDatabaseFile();
			} else {
				timer.schedule(timerTask, SPLASH_SCREEN_DURATION);
			}
		}

	}

	private class DownloadDatabaseFileTask extends
			AsyncTask<Void, Integer, Void> {

		private Activity activity;

		private ProgressDialog progressDialog;

		private URL url;
		private URLConnection urlConnection;
		private int databaseFileLength;
		private File outputFile;

		public DownloadDatabaseFileTask(Activity activity) {
			this.activity = activity;

			progressDialog = new ProgressDialog(activity);
			progressDialog.setMessage("Pobieranie pliku bazy");
			progressDialog.setIndeterminate(false);
			progressDialog.setMax(100);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			progressDialog.show();
		}

		@Override
		protected Void doInBackground(Void... params) {
			try {
				url = new URL(sDatabaseFileUrl);

				urlConnection = url.openConnection();
				urlConnection.connect();

				databaseFileLength = urlConnection.getContentLength();

				outputFile = new File(activity.getCacheDir(), "pps_database.db");

				InputStream input = new BufferedInputStream(url.openStream());
				OutputStream output = new FileOutputStream(outputFile);

				byte data[] = new byte[1024];
				long total = 0;
				int count;
				while ((count = input.read(data)) != -1) {
					total += count;
					publishProgress((int) (total * 100 / databaseFileLength));
					output.write(data, 0, count);
				}

				output.flush();
				output.close();
				input.close();
			} catch (MalformedURLException e) {
				Log.e(TAG, "Zly adres pliku z baza danych");
			} catch (IOException e) {
				Log.e(TAG, "Blad zapisu pliku danych na urzadzeniu");
			}

			return null;
		}

		@Override
		protected void onProgressUpdate(Integer... progress) {
			super.onProgressUpdate(progress);
			progressDialog.setProgress(progress[0]);
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			progressDialog.dismiss();
				sCasheFile = outputFile;
				updateDatabase();
		}

	}

	private class CopyDatabaseFile extends AsyncTask<Void, Integer, Void> {

		private DatabaseHelper dbHelper;
		private Activity activity;
		private ProgressDialog progressDialog;

		public CopyDatabaseFile(Activity activity) {
			this.activity = activity;
			this.dbHelper = new DatabaseHelper(activity);

			progressDialog = new ProgressDialog(activity);
			progressDialog.setMessage("Kopiowanie pliku bazy");
			progressDialog.setIndeterminate(false);
			progressDialog.setMax(100);
			progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			progressDialog.show();
		}

		@Override
		protected Void doInBackground(Void... params) {
			if (checkDatabase()) {

				try {
					File inFile = sCasheFile;

					long f_length = inFile.length();
					BufferedInputStream buffInput = new BufferedInputStream(
							new FileInputStream(inFile));

					File outFile = new File(DATABASE_PATH, DATABASE_NAME);

					OutputStream out = new FileOutputStream(outFile);

					byte data[] = new byte[1024];
					long total = 0;
					int count;
					while ((count = buffInput.read(data)) != -1) {
						total += count;
						publishProgress((int) (total * 100 / f_length));
						out.write(data, 0, count);
					}

					out.flush();
					out.close();
					buffInput.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			return null;
		}

		@Override
		protected void onProgressUpdate(Integer... progress) {
			super.onProgressUpdate(progress);
			progressDialog.setProgress(progress[0]);
		}

		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			progressDialog.dismiss();

			timer.schedule(timerTask, SPLASH_SCREEN_DURATION);
		}

		private boolean checkDatabase() {
			SQLiteDatabase db = null;

			db = dbHelper.getReadableDatabase();

			if (db != null) {
				db.close();
			}

			return db != null ? true : false;
		}

	}

}
